package cn.wen.java.jni;

import java.io.File;
import java.io.IOException;

import org.apache.commons.io.FilenameUtils;
import org.apache.log4j.Logger;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;

/**
 * Title：Jacob辅助类
 * <p>
 * Description：Jacob允许在java中调用com接口自动组件，它使用JNI（本地调用程序）来进行本地调用COM库。它可运行在x86和支持32位和64位Java虚拟机 X64的环境。
 * <p>
 * Copyright：Copyright (c) 2010-2012
 * 
 * @author <a href="mailto:ct_wen@qq.com">ctwen</a>, 温承瑭
 * @version Revision：1.0 Date：2010/3/9 Description：初完成。
 *          <p>
 */
public final class JacobUtils {

    private static Logger log = Logger.getLogger(JacobUtils.class);

    public static final int WORD_HTML = 8;
    public static final int WORD_TXT = 7;
    public static final int TEXT = 42; // 3
    public static final int TEXT_ALIGNMENT = 36; // 文本-对齐的
    public static final int TEXT_SEPARATOR = 6; // 文本-分隔符
    public static final int EXCEL_HTML = 44;
    public static final int EXCEL_HTM = 45; // 单个文件网页
    public static final int EXCEL_XML = 46;
    public static final int MSOFFICE_EXCEL_SAVEAS_PDF = 57;

    /**
     * <PRE>
     * 将指定路径的MSExcel文件，在文件目录下，转换为PDF文件，文件主名与MSExcel文件一致。
     * 
     * 注：需要MS OFFICE 2010 COM组件，且打印服务需开启。
     * </PRE>
     * 
     * @param srcPath 
     * @throws IOException 
     * @see cn.wen.java.jni.JacobUtils#excelSaveAsPDF(String, String)
     */
    public static void excelSaveAsPDF(String srcPath) throws IOException {
	excelSaveAsPDF(srcPath, FilenameUtils.getFullPath(srcPath) + FilenameUtils.getBaseName(srcPath) + ".pdf");
    }

    /**
     * <PRE>
     * 将指定路径的MSExcel文件，转换为指定路径的PDF文件。
     * 
     * 注：需要MS OFFICE 2010 COM组件，且打印服务需开启。
     * </PRE>
     * 
     * @param srcPath
     * @param dstPath
     * @throws IOException
     */
    public static void excelSaveAsPDF(String srcPath, String dstPath) throws IOException {
	File src = new File(srcPath), dst = new File(dstPath);
	srcPath = src.getCanonicalPath();
	dstPath = dst.getCanonicalPath();

	ComThread.InitSTA();

	ActiveXComponent axcom = null;
	Dispatch excel_Open = null;

	try {
	    axcom = new ActiveXComponent("Excel.Application");
	    axcom.setProperty("Visible", new Variant(false));
	    Dispatch workBooks = axcom.getProperty("Workbooks").toDispatch();

	    excel_Open = Dispatch.invoke(workBooks, "Open", Dispatch.Method,
		    new Object[] { srcPath, new Variant(false), new Variant(false) }, new int[9]).toDispatch();

	    Dispatch.invoke(excel_Open, "SaveAs", Dispatch.Method, new Object[] { dstPath,
		    new Variant(MSOFFICE_EXCEL_SAVEAS_PDF), new Variant(false) }, new int[0]);

	    log.debug("Started convert from : " + srcPath + " to " + dstPath);
	}
	catch (Exception e) {
	    e.printStackTrace();
	}
	finally {
	    close(excel_Open);
	    quit(axcom);
	}

	ComThread.Release();
    }

    private static void close(Dispatch dispatch) {
	if (null != dispatch) Dispatch.call(dispatch, "Close", new Variant(false));
    }

    private static void quit(ActiveXComponent actcom) {
	if (null != actcom) actcom.invoke("Quit", new Variant[] {});
    }

}
